JavaScript Temporal Duration — vaqt oraliqlarini aniq hisoblash, taqqoslash va formatlash uchun zamonaviy API bilan tanishing. Vaqt davrlarini global miqyosda ishonch bilan boshqarishni o'rganing va Date obyektlari bilan bog'liq keng tarqalgan xatolardan saqlaning.
JavaScript Temporal Duration: Global Ilovalar Uchun Vaqt Oralig'i Arifmetikasi va Formatlashni O'zlashtirish
Dasturiy ta'minotni ishlab chiqishda vaqtni boshqarish juda murakkabdir. Qit'alararo loyiha muddatlarini kuzatishdan tortib xalqaro video konferensiyalarni rejalashtirishgacha, vaqt oraliqlari, vaqt mintaqalari va yozgi vaqtga o'tishning nozikliklari tezda sezilmas, ammo jiddiy xatolarga olib kelishi mumkin. O'nlab yillar davomida JavaScript dasturchilari o'rnatilgan Date obyekti bilan kurashib kelishdi, bu vosita oddiy sana-vaqt nuqtalari uchun funksional bo'lsa-da, aniq vaqt oralig'i arifmetikasi va mustahkam, global miqyosda vaqtni boshqarishda yetarli emas.
JavaScript Temporal API — bu JavaScript-da sanalar va vaqtlar bilan ishlash uchun zamonaviy, mustahkam va qulay API taqdim etishga mo'ljallangan inqilobiy taklifdir. Uning kuchli yangi turlari orasida Temporal.Duration vaqt oraliqlari bilan ishlash uchun yakuniy yechim sifatida ajralib turadi. Ushbu maqola sizni Temporal.Duration bilan chuqur tanishtiradi, uning arifmetika, taqqoslash va aqlli formatlash imkoniyatlarini o'rganadi, bu esa ilovalaringizning vaqtni global aniqlik va ravshanlik bilan boshqarishini ta'minlaydi.
Global logistika tizimini, moliyaviy savdo platformasini yoki ko'p vaqt mintaqali tadbirlar rejalashtiruvchisini yaratyapsizmi, Temporal.Durationni tushunish vaqt bilan bog'liq noaniqliklarni bartaraf etish va ishonchli, xalqaro miqyosdagi foydalanuvchi tajribasini taqdim etish uchun juda muhimdir.
Vaqt Ortaliklari Uchun JavaScript Date Obyektining Kamchiliklari
Temporal.Durationning paydo bo'lishini nishonlashdan oldin, mavjud Date obyektining cheklovlarini, ayniqsa vaqt oraliqlari bilan ishlashda tushunish muhimdir. Date obyekti Unix epoxasidan (1970 yil 1-yanvar, UTC) beri o'tgan millisekundlarda o'lchanadigan aniq bir vaqt nuqtasini ifodalaydi. U oddiy arifmetikani bajarish uchun ishlatilishi mumkin bo'lsa-da, uni mustahkam davomiylikni boshqarish uchun yaroqsiz qiladigan bir nechta o'ziga xos kamchiliklarga ega:
-
O'zgaruvchanlik:
Dateobyektlari o'zgaruvchandir.Dateobyektidagi har qanday operatsiya uning ichki holatini o'zgartiradi, bu esa kutilmagan yon ta'sirlarga va kuzatish qiyin bo'lgan xatolarga olib kelishi mumkin, ayniqsa murakkab ilovalarda yoki bir vaqtning o'zida ishlaydigan muhitlarda.const d = new Date('2023-01-15T10:00:00Z'); const d2 = d; // d2 endi d bilan bir xil obyektga ishora qiladi d.setHours(d.getHours() + 1); console.log(d.toISOString()); // 2023-01-15T11:00:00.000Z console.log(d2.toISOString()); // 2023-01-15T11:00:00.000Z (d2 ham o'zgardi!) -
Davomiylik Tushunchasining Yo'qligi:
Dateobyektida "davomiylik" yoki "davr" tushunchasi to'g'ridan-to'g'ri mavjud emas. Ikki sana orasidagi farqni hisoblash millisekundlar sonini beradi, keyin uni yillar, oylar, kunlar va hokazolarga qo'lda aylantirish kerak bo'ladi. Bu qo'lda aylantirish xatolarga moyil, ayniqsa o'zgaruvchan uzunlikdagi oylar yoki kabisa yillari bilan ishlashda.const date1 = new Date('2023-01-01T00:00:00Z'); const date2 = new Date('2023-03-01T00:00:00Z'); const diffMs = date2.getTime() - date1.getTime(); // Bu necha oy? Kabisa yillari-chi? // (diffMs / (1000 * 60 * 60 * 24 * 30)) eng yaxshi holatda taxminiy hisobdir. console.log(`Millisekundlardagi farq: ${diffMs}`); console.log(`Taxminiy kunlar: ${diffMs / (1000 * 60 * 60 * 24)}`); // Kunlar uchun ishlaydi, lekin oylar/yillar uchun mustahkam emas -
Vaqt Mintaqasi Noaniqligi:
Dateobyektlari ko'pincha mahalliy vaqt va UTC ni aralashtirib yuboradi. Ular ichki ravishda UTC millisekundlarini saqlasa-da, ularning metodlari sukut bo'yicha tizimning mahalliy vaqt mintaqasida ishlaydi, bu esa taqsimlangan tizimlar yoki xalqaro foydalanuvchilar bilan ishlashda chalkashlik va nomuvofiqliklarga olib keladi. - Yozgi Vaqtga O'tish (DST) Muammolari: Yozgi vaqtga o'tish kunlarning 23 yoki 25 soat davom etishiga olib kelishi mumkin. Oddiy arifmetika (masalan, sanaga 24 soat qo'shish) har doim ham keyingi kalendar kuniga olib kelmasligi mumkin, bu esa "kun" 24 soatlik qat'iy davr deb hisoblanganda noto'g'ri hisob-kitoblarga olib keladi.
Bu cheklovlar tarixan dasturchilarni Moment.js yoki date-fns kabi uchinchi tomon kutubxonalariga tayanishga yoki vaqt oraliqlarini to'g'ri boshqarish uchun murakkab, xatolarga moyil maxsus kod yozishga majbur qilgan. Temporal bu imkoniyatlarni JavaScript-ga tabiiy ravishda olib kelishni maqsad qilgan.
JavaScript Temporal bilan tanishuv: Vaqtga Zamonaviy Yondashuv
Temporal API — bu eskirgan Date obyektining zamonaviy o'rnini bosuvchi sifatida ishlab chiqilgan JavaScript-dagi keng qamrovli, yangi global obyektdir. Uning asosiy tamoyillari o'zgarmaslik, vaqt mintaqasini aniq boshqarish va turli vaqt tushunchalari o'rtasida mas'uliyatni aniq ajratishdir. Temporal bir nechta yangi sinflarni taqdim etadi, ularning har biri vaqtning alohida jihatini ifodalaydi:
Temporal.Instant: Har qanday taqvim yoki vaqt mintaqasidan mustaqil bo'lgan aniq, bir ma'noli vaqt nuqtasi (Unix vaqt belgisiga o'xshash, lekin nanosekund aniqlikda).Temporal.ZonedDateTime: Muayyan kalendar va vaqt mintaqasidagi aniq bir vaqt nuqtasi. Bu foydalanuvchi uchun aniq sana va vaqtning eng to'liq ko'rinishi.Temporal.PlainDate: Vaqt yoki vaqt mintaqasisiz kalendar sanasi (yil, oy, kun).Temporal.PlainTime: Sana yoki vaqt mintaqasisiz soat vaqti (soat, daqiqa, soniya va hk.).Temporal.PlainDateTime: Vaqt mintaqasisiz kalendar sanasi va soat vaqtining birgalikdagi ko'rinishi.Temporal.PlainYearMonth: Kalendar tizimidagi ma'lum bir yil va oy.Temporal.PlainMonthDay: Kalendar tizimidagi ma'lum bir oy va kun.Temporal.Duration: "5 soat va 30 daqiqa" yoki "2 kun" kabi ishorali vaqt uzunligi. Bu bizning ushbu qo'llanmadagi diqqat markazimiz.
Barcha Temporal obyektlari o'zgarmasdir, ya'ni vaqtni qo'shish yoki ayirish kabi operatsiyalar mavjud obyektlarni o'zgartirish o'rniga yangi obyektlar yaratadi, bu esa bashoratlilikni oshiradi va xatolarni kamaytiradi.
Temporal.Durationni Tushunish
Temporal.Duration vaqt uzunligini ifodalaydi. Muhimi, u ma'lum bir boshlanish yoki tugash nuqtasidan mustaqil. Bu shunchaki "qancha vaqt" o'tganini yoki o'tishini bildiradi. U yillar, oylar, haftalar, kunlar, soatlar, daqiqalar, soniyalar, millisekundlar, mikrosekundlar va nanosekundlardan iborat bo'lishi mumkin. Har bir komponent butun son bo'lib, ijobiy yoki manfiy bo'lishi mumkin.
Masalan, "2 soat va 30 daqiqa" bu davomiylikdir. "1-yanvardan 1-martgacha bo'lgan davr" ikki aniq nuqta orasidagi davomiylik bo'lib, uni Temporal.Duration bilan *ifodalash* mumkin, lekin Durationning o'zi shunchaki intervaldir.
Duration Yaratish
Temporal.Duration obyektlarini yaratishning bir nechta oddiy usullari mavjud:
1. Konstruktordan Foydalanish
Konstruktor har bir komponentni to'g'ridan-to'g'ri belgilash imkonini beradi. E'tibor bering, argumentlar eng katta birlikdan (yillar) eng kichigiga (nanosekundlar) qarab tartiblangan.
// new Temporal.Duration(yillar, oylar, haftalar, kunlar, soatlar, daqiqalar, soniyalar, millisekundlar, mikrosekundlar, nanosekundlar)
// 2 soat va 30 daqiqalik davomiylik
const duration1 = new Temporal.Duration(0, 0, 0, 0, 2, 30, 0, 0, 0, 0);
console.log(duration1.toString()); // P2H30M
// 1 yil, 2 oy, 3 kunlik davomiylik
const duration2 = new Temporal.Duration(1, 2, 0, 3);
console.log(duration2.toString()); // P1Y2M3D
// -5 kunlik davomiylik
const duration3 = new Temporal.Duration(0, 0, 0, -5);
console.log(duration3.toString()); // P-5D
2. Temporal.Duration.from()dan Obyekt Bilan Foydalanish
Bu ko'pincha davomiyliklarni yaratishning eng o'qilishi oson usuli bo'lib, faqat kerakli komponentlarni belgilash imkonini beradi.
// 1.5 soatlik davomiylik
const halfHourDuration = Temporal.Duration.from({ hours: 1, minutes: 30 });
console.log(halfHourDuration.toString()); // P1H30M
// 7 kunlik davomiylik (1 hafta)
const oneWeekDuration = Temporal.Duration.from({ days: 7 });
console.log(oneWeekDuration.toString()); // P7D
// Kasrli soniyali davomiylik (masalan, 2.5 soniya)
const twoPointFiveSeconds = Temporal.Duration.from({ seconds: 2, milliseconds: 500 });
console.log(twoPointFiveSeconds.toString()); // PT2.5S
// Manfiy davomiylik
const negativeDuration = Temporal.Duration.from({ minutes: -45 });
console.log(negativeDuration.toString()); // PT-45M
3. Temporal.Duration.from()dan ISO 8601 Satri Bilan Foydalanish
Temporal ISO 8601 davomiylik formatidan foydalanadi, bu davomiyliklarni ifodalash uchun standartdir. Bu tashqi ma'lumotlar manbalaridan davomiyliklarni tahlil qilish uchun ajoyib.
Format odatda P[yillar]Y[oylar]M[haftalar]W[kunlar]DT[soatlar]H[daqiqalar]M[soniyalar]S ko'rinishida bo'ladi. T sana komponentlarini vaqt komponentlaridan ajratadi.
// 1 yil, 2 oy, 3 kun
const isoDuration1 = Temporal.Duration.from('P1Y2M3D');
console.log(isoDuration1.toString()); // P1Y2M3D
// 4 soat, 5 daqiqa, 6 soniya
const isoDuration2 = Temporal.Duration.from('PT4H5M6S');
console.log(isoDuration2.toString()); // PT4H5M6S
// Birlashtirilgan davomiylik
const isoDuration3 = Temporal.Duration.from('P7DT12H30M');
console.log(isoDuration3.toString()); // P7DT12H30M
// Kasrli soniyalar ham qo'llab-quvvatlanadi
const isoDuration4 = Temporal.Duration.from('PT1.5S');
console.log(isoDuration4.toString()); // PT1.5S
Durationlar Bilan Arifmetik Amallar Bajarish
Temporal.Durationning haqiqiy kuchi uning arifmetik imkoniyatlarida namoyon bo'ladi. Siz davomiyliklarni qo'shishingiz, ayirishingiz, ko'paytirishingiz va bo'lishingiz, shuningdek ularni boshqa Temporal sana-vaqt turlariga qo'shishingiz/ayirishingiz mumkin. Barcha operatsiyalar o'zgarmaslik tufayli yangi Temporal.Duration obyektlarini qaytaradi.
Durationlarni Qo'shish
add() metodi ikki davomiylikni birlashtiradi.
const sprintDuration = Temporal.Duration.from({ weeks: 2 });
const bufferDuration = Temporal.Duration.from({ days: 3 });
const totalProjectTime = sprintDuration.add(bufferDuration);
console.log(totalProjectTime.toString()); // P2W3D (yoki keyinroq normallashtirilsa P17D)
// Manfiy duration qo'shish ayirishga teng
const result = Temporal.Duration.from({ hours: 5 }).add({ hours: -2 });
console.log(result.toString()); // PT3H
Shuningdek, davomiylikni har qanday Temporal sana/vaqt obyektiga qo'shishingiz mumkin. Bu yerda mo''jiza sodir bo'ladi, chunki Temporal kerak bo'lganda vaqt mintaqasi o'zgarishlari va yozgi vaqtga o'tishlarni to'g'ri boshqaradi.
const projectStart = Temporal.PlainDateTime.from('2023-10-26T09:00:00');
const projectDuration = Temporal.Duration.from({ days: 10, hours: 4 });
const projectEnd = projectStart.add(projectDuration);
console.log(projectEnd.toString()); // 2023-11-05T13:00:00
// ZonedDateTime bilan vaqt mintaqasi qoidalari to'g'ri qo'llaniladi
const meetingStartUTC = Temporal.ZonedDateTime.from('2024-03-09T14:00:00[UTC]');
const meetingDuration = Temporal.Duration.from({ hours: 1, minutes: 45 });
const meetingEndUTC = meetingStartUTC.add(meetingDuration);
console.log(meetingEndUTC.toString()); // 2024-03-09T15:45:00+00:00[UTC]
// Yozgi vaqtga o'tish chegarasini kesib o'tish misoli ('Europe/Berlin' 2024-03-31 kuni soat 03:00 da o'zgaradi deb faraz qilsak)
const springForwardStart = Temporal.ZonedDateTime.from('2024-03-30T22:00:00[Europe/Berlin]');
const twentyFourHours = Temporal.Duration.from({ hours: 24 });
const nextDay = springForwardStart.add(twentyFourHours); // Haqiqiy 24 soat qo'shadi
console.log(springForwardStart.toString()); // 2024-03-30T22:00:00+01:00[Europe/Berlin]
console.log(nextDay.toString()); // 2024-03-31T23:00:00+02:00[Europe/Berlin] (Mahalliy vaqt bir soat o'tkazib yuborildi)
E'tibor bering, Berlindagi (UTC+1) 2024-03-30T22:00:00 ga 24 soat qo'shish natijasi 2024-03-31T23:00:00 (endi UTC+2) bo'ladi. Soat bir soat oldinga surildi, shuning uchun mahalliy soat vaqti boshlang'ich soat vaqtiga nisbatan bir soat keyinroq bo'ladi. Bu `ZonedDateTime`da arifmetika bajarilganda Temporalning vaqt mintaqasi va yozgi vaqtga o'tishni qanday hisobga olishini aniq ko'rsatadi.
Durationlarni Ayirish
subtract() metodi add() ga o'xshab ishlaydi, lekin u vaqtni ayiradi.
const deadlineDuration = Temporal.Duration.from({ days: 30 });
const gracePeriod = Temporal.Duration.from({ days: 5 });
const effectiveDeadline = deadlineDuration.subtract(gracePeriod);
console.log(effectiveDeadline.toString()); // P25D
const taskEnd = Temporal.PlainDateTime.from('2023-12-01T17:00:00');
const taskDuration = Temporal.Duration.from({ hours: 8, minutes: 30 });
const taskStart = taskEnd.subtract(taskDuration);
console.log(taskStart.toString()); // 2023-12-01T08:30:00
Durationlarni Ko'paytirish va Bo'lish
multiply() va divide() metodlari davomiylik komponentlarini berilgan omilga ko'ra o'lchaydi. Bu vazifaning bir nechta takrorlanishi uchun umumiy vaqtni hisoblash kabi stsenariylarda foydalidir.
const trainingSession = Temporal.Duration.from({ minutes: 45 });
const weeklyTraining = trainingSession.multiply(5); // Haftasiga beshta mashg'ulot
console.log(weeklyTraining.toString()); // PT225M
const totalProjectHours = Temporal.Duration.from({ hours: 160 });
const teamMembers = 4;
const hoursPerMember = totalProjectHours.divide(teamMembers);
console.log(hoursPerMember.toString()); // PT40H
Durationlarni Inkor Qilish
negate() metodi davomiylikning barcha komponentlarining ishorasini o'zgartiradi. Ijobiy davomiylik manfiy bo'ladi va aksincha.
const delayDuration = Temporal.Duration.from({ hours: 3 });
const advanceDuration = delayDuration.negate();
console.log(delayDuration.toString()); // PT3H
console.log(advanceDuration.toString()); // PT-3H
Durationlarning Mutlaq Qiymati
abs() metodi barcha komponentlari ijobiy qilingan yangi Temporal.Duration qaytaradi, bu esa uning ishorasidan qat'i nazar, davomiylikning kattaligini beradi.
const negativeDelay = Temporal.Duration.from({ minutes: -60 });
const positiveDuration = negativeDelay.abs();
console.log(negativeDelay.toString()); // PT-60M
console.log(positiveDuration.toString()); // PT60M
Durationlarni Taqqoslash va Normallashtirish
Davomiyliklarni taqqoslash, ayniqsa turli birliklar ishtirok etganda (masalan, 1 oy 30 kunga tengmi?) qiyin bo'lishi mumkin. Temporal bu murakkabliklarni hal qilish uchun ham taqqoslash, ham normallashtirish vositalarini taqdim etadi.
compare() Yordamida Durationlarni Taqqoslash
Statik Temporal.Duration.compare(duration1, duration2, options) metodi quyidagilarni qaytaradi:
-1agarduration1duration2dan kichik bo'lsa0agarduration1duration2ga teng bo'lsa1agarduration1duration2dan katta bo'lsa
Muhimi, yillar, oylar yoki haftalar kabi o'zgaruvchan uzunlikdagi birliklarni o'z ichiga olgan davomiyliklarni taqqoslashda ko'pincha relativeTo opsiyasini taqdim etish kerak. Bu parametr bu birliklarni qanday talqin qilish uchun kontekst taqdim etuvchi `Temporal.ZonedDateTime` yoki `Temporal.PlainDateTime` obyektidir (masalan, ma'lum bir oyda yoki yilda necha kun bor).
const oneHour = Temporal.Duration.from({ hours: 1 });
const sixtyMinutes = Temporal.Duration.from({ minutes: 60 });
console.log(Temporal.Duration.compare(oneHour, sixtyMinutes)); // 0 (Ular teng)
const oneMonth = Temporal.Duration.from({ months: 1 });
const thirtyDays = Temporal.Duration.from({ days: 30 });
// relativeTo bo'lmasa, oy/yil taqqoslashlari qiyin
console.log(Temporal.Duration.compare(oneMonth, thirtyDays)); // 0 (Temporal kontekstsiz o'rtacha qiymatga asoslangan holda taxmin qiladi)
// relativeTo bilan taqqoslash kontekst kalendariga asoslangan holda aniq bo'ladi
const startOfJanuary = Temporal.PlainDate.from('2023-01-01');
const endOfFebruaryLeap = Temporal.PlainDate.from('2024-02-01'); // Kabisa yili
// 2023 yil yanvarida 1 oy 31 kun
const comparisonJan = Temporal.Duration.compare(oneMonth, thirtyDays, { relativeTo: startOfJanuary });
console.log(`1 oy vs 30 kun, Yan 2023: ${comparisonJan}`); // 1 (1 oy > 30 kun)
// 2024 yil fevralida (kabisa yili), 1 oy 29 kun
const comparisonFeb = Temporal.Duration.compare(oneMonth, thirtyDays, { relativeTo: endOfFebruaryLeap });
console.log(`1 oy vs 30 kun, Fev 2024: ${comparisonFeb}`); // -1 (1 oy < 30 kun)
normalize() va round() Yordamida Durationlarni Normallashtirish
Davomiyliklar turli yo'llar bilan ifodalanishi mumkin (masalan, 90 daqiqa yoki 1 soat 30 daqiqa). Normallashtirish va yaxlitlash bu ifodalarni bir xillik va namoyish uchun standartlashtirishga yordam beradi.
normalize()
normalize() metodi imkon qadar davomiylik komponentlarini soddalashtiradi (masalan, 60 daqiqa 1 soatga, 24 soat 1 kunga aylanadi, agar oylar/yillar ishtirok etsa `relativeTo` konteksti ruxsat bersa).
const longMinutes = Temporal.Duration.from({ minutes: 90 });
console.log(longMinutes.toString()); // PT90M
console.log(longMinutes.normalize().toString()); // PT1H30M
const multipleDays = Temporal.Duration.from({ hours: 48 });
console.log(multipleDays.toString()); // PT48H
console.log(multipleDays.normalize().toString()); // P2D
round()
round() metodi davomiyliklarni ma'lum birliklarga aylantirish va yaxlitlash uchun kuchliroqdir. U quyidagi opsiyalar obyektini qabul qiladi:
largestUnit: Chiqarishda kiritiladigan eng katta birlik (masalan, 'years', 'days', 'hours').smallestUnit: Chiqarishda kiritiladigan eng kichik birlik (masalan, 'minutes', 'seconds', 'milliseconds').roundingIncrement: Eng kichik birlikni yaxlitlash uchun butun son (masalan, eng yaqin 5 daqiqaga yaxlitlash uchun 5).roundingMode: Tenglik holatlarini qanday hal qilish ('halfExpand', 'trunc', 'ceil', 'floor').relativeTo: Yillar, oylar yoki haftalarni o'z ichiga olgan davomiyliklarni yaxlitlash uchun talab qilinadi.
const complexDuration = Temporal.Duration.from({ hours: 2, minutes: 45, seconds: 30 });
// Eng yaqin soatgacha yaxlitlash
const roundedToHours = complexDuration.round({ smallestUnit: 'hour' });
console.log(roundedToHours.toString()); // PT3H
// Soatlarni saqlagan holda eng yaqin 30 daqiqagacha yaxlitlash
const roundedTo30Minutes = complexDuration.round({
largestUnit: 'hour',
smallestUnit: 'minute',
roundingIncrement: 30
});
console.log(roundedTo30Minutes.toString()); // PT3H
const preciseDuration = Temporal.Duration.from({ minutes: 123, seconds: 45 });
// Soat va daqiqalar sifatida ko'rsatish
const formattedDuration = preciseDuration.round({ largestUnit: 'hour', smallestUnit: 'minute' });
console.log(formattedDuration.toString()); // PT2H4M
// Oylar/yillar bilan yaxlitlash relativeTo talab qiladi
const longTermDuration = Temporal.Duration.from({ months: 1, days: 10 });
const referenceDate = Temporal.PlainDate.from('2023-01-15');
// Sanaga nisbatan oylargacha yaxlitlash
const roundedToMonths = longTermDuration.round({ largestUnit: 'month', smallestUnit: 'month', relativeTo: referenceDate });
console.log(roundedToMonths.toString()); // P1M
Temporal Obyektlari Orasidagi Durationlarni Hisoblash
Davomiyliklarning eng ko'p qo'llaniladigan usullaridan biri bu ikki aniq vaqt nuqtasi orasidagi vaqt oralig'ini hisoblashdir. Temporal buning uchun o'zining sana-vaqt obyektlarida until() va since() metodlarini taqdim etadi.
until() Metodi
until() metodi qabul qiluvchi obyektdan argument obyektigacha bo'lgan davomiylikni hisoblaydi. U boshlanish nuqtasini o'z ichiga oladi va tugash nuqtasini o'z ichiga olmaydi. U kerakli birliklarni va yaxlitlash xatti-harakatlarini belgilash uchun round() ga o'xshash opsiyalar obyektini qabul qiladi.
const startDate = Temporal.PlainDate.from('2023-01-01');
const endDate = Temporal.PlainDate.from('2023-03-15');
// Mumkin bo'lgan eng katta birliklarda duration (oylar, keyin kunlar)
const projectLength = startDate.until(endDate);
console.log(projectLength.toString()); // P2M14D
// Faqat kunlardagi duration
const totalDays = startDate.until(endDate, { largestUnit: 'day' });
console.log(totalDays.toString()); // P73D
// Vaqt mintaqalarini hisobga olgan holda ikki aniq vaqt orasidagi duration
const meetingStart = Temporal.ZonedDateTime.from('2024-07-20T10:00:00[America/New_York]');
const meetingEnd = Temporal.ZonedDateTime.from('2024-07-20T11:30:00[America/New_York]');
const elapsedMeetingTime = meetingStart.until(meetingEnd, { largestUnit: 'hour', smallestUnit: 'minute' });
console.log(elapsedMeetingTime.toString()); // PT1H30M
// Vaqt mintaqalariaro duration (NYC dan Londongacha)
const nyStartTime = Temporal.ZonedDateTime.from('2024-08-01T09:00:00[America/New_York]');
const londonEndTime = Temporal.ZonedDateTime.from('2024-08-01T17:00:00[Europe/London]');
const travelDuration = nyStartTime.until(londonEndTime);
console.log(travelDuration.toString()); // PT13H (Haqiqiy o'tgan vaqt, soatdagi farq emas)
Oxirgi misol ayniqsa qiziq. Nyu-York Londondan 5 soat orqada bo'lishiga va soat vaqtlari bir kunda ertalabki 9 va kechki 5 bo'lishiga qaramay, until() metodi 13 soatlik haqiqiy o'tgan vaqtni to'g'ri hisoblaydi. Buning sababi, ZonedDateTime vaqt mintaqasi farqini yashirin tarzda boshqaradi.
since() Metodi
since() metodi until()ning teskarisidir. U argument obyektidan qabul qiluvchi obyektgacha bo'lgan davomiylikni hisoblaydi, agar argument qabul qiluvchiga nisbatan kelajakda bo'lsa, manfiy davomiylikni qaytaradi.
const currentDateTime = Temporal.ZonedDateTime.from('2024-06-15T12:00:00[Europe/Paris]');
const historicEvent = Temporal.ZonedDateTime.from('2024-01-01T00:00:00[Europe/Paris]');
const timeSinceEvent = currentDateTime.since(historicEvent, { largestUnit: 'month', smallestUnit: 'day' });
console.log(timeSinceEvent.toString()); // P5M14D
const futureDate = Temporal.PlainDate.from('2025-01-01');
const pastDate = Temporal.PlainDate.from('2024-01-01');
const durationFromFuture = pastDate.since(futureDate);
console.log(durationFromFuture.toString()); // P-1Y
Hisoblangan Durationlar Uchun Turli Birliklarni va Yaxlitlashni Boshqarish
Davomiyliklarni hisoblashda, ayniqsa yosh, o'tgan vaqt yoki ortga hisoblash uchun odam o'qiy oladigan ko'rinishga ega bo'lish uchun `largestUnit` va `smallestUnit`ni belgilash ko'pincha zarur.
const birthDate = Temporal.PlainDate.from('1990-07-15');
const today = Temporal.PlainDate.from('2024-06-15');
// Yoshni yillar, oylar va kunlarda hisoblash
const age = birthDate.until(today, { largestUnit: 'year', smallestUnit: 'day' });
console.log(`Yosh: ${age.years} yil, ${age.months} oy, ${age.days} kun`); // Yosh: 33 yil, 11 oy, 0 kun
// Vazifa uchun qolgan vaqtni soat va daqiqalarda hisoblash
const now = Temporal.Instant.fromEpochSeconds(Date.now() / 1000);
const deadline = Temporal.Instant.from('2024-07-01T09:00:00Z');
const timeLeft = now.until(deadline, { largestUnit: 'hour', smallestUnit: 'minute', roundingMode: 'ceil' });
console.log(`Qolgan vaqt: ${timeLeft.hours} soat va ${timeLeft.minutes} daqiqa.`); // Misol: Qolgan vaqt: 355 soat va 38 daqiqa.
Global Auditoriya Uchun Durationlarni Formatlash
Temporal.Duration vaqt oraliqlarining aniq, dasturiy ifodalarini taqdim etsa-da, uning o'rnatilgan toLocaleString() metodi yo'q. Bu ataylab shunday qilingan: davomiyliklar mavhum vaqt uzunliklari bo'lib, ularning ko'rinishi kontekstga, tilga va kerakli tafsilot darajasiga qarab keskin o'zgarishi mumkin. Dasturchi sifatida siz davomiyliklarni foydalanuvchiga qulay, global tushunarli tarzda taqdim etish uchun mas'ulsiz.
ISO 8601 Satr Ko'rinishi
Temporal.Duration obyektining standart toString() metodi uning ISO 8601 satr ko'rinishini qaytaradi. Bu mashinadan-mashinaga aloqa, serializatsiya va saqlash uchun ajoyib, lekin kamdan-kam hollarda oxirgi foydalanuvchilarga to'g'ridan-to'g'ri ko'rsatish uchun ishlatiladi.
const examDuration = Temporal.Duration.from({ hours: 2, minutes: 15 });
console.log(examDuration.toString()); // PT2H15M
const holidayDuration = Temporal.Duration.from({ weeks: 2, days: 3 });
console.log(holidayDuration.toString()); // P2W3D
O'qish Osonligi va Xalqarolashtirish Uchun Qo'lda Formatlash
Foydalanuvchiga ko'rsatish uchun odatda davomiylik komponentlarini ajratib olasiz va ularni satr interpolyatsiyasi va JavaScript-ning Intl APIsi yordamida formatlaysiz.
Bu yerda davomiylikni formatlaydigan maxsus funksiya misoli keltirilgan:
function formatDurationToHumanReadable(duration, locale = 'uz-UZ') {
const parts = [];
// Mahalliy tilga mos raqamlarni formatlash uchun Intl.NumberFormat ishlatilmoqda
const numberFormatter = new Intl.NumberFormat(locale);
if (duration.years !== 0) {
parts.push(numberFormatter.format(duration.years) + ' yil');
}
if (duration.months !== 0) {
parts.push(numberFormatter.format(duration.months) + ' oy');
}
if (duration.weeks !== 0) {
parts.push(numberFormatter.format(duration.weeks) + ' hafta');
}
if (duration.days !== 0) {
parts.push(numberFormatter.format(duration.days) + ' kun');
}
if (duration.hours !== 0) {
parts.push(numberFormatter.format(duration.hours) + ' soat');
}
if (duration.minutes !== 0) {
parts.push(numberFormatter.format(duration.minutes) + ' daqiqa');
}
if (duration.seconds !== 0) {
// Agar soniyalarda kasr qismlari bo'lsa, ko'rsatish uchun ularni yaxlitlash
const roundedSeconds = numberFormatter.format(duration.seconds.toFixed(0)); // Yoki bitta o'nlik uchun toFixed(1)
parts.push(roundedSeconds + ' soniya');
}
if (parts.length === 0) {
// Duration nolga teng yoki juda kichik bo'lgan holatlarni (masalan, faqat nanosekundlar) qayta ishlash
if (duration.milliseconds !== 0 || duration.microseconds !== 0 || duration.nanoseconds !== 0) {
const totalMs = duration.milliseconds + duration.microseconds / 1000 + duration.nanoseconds / 1_000_000;
return numberFormatter.format(totalMs.toFixed(2)) + ' millisekund';
}
return '0 soniya';
}
// Qismlarni vergul bilan va oxirgi qism uchun 'va' bilan birlashtirish
if (parts.length > 1) {
const lastPart = parts.pop();
return parts.join(', ') + ' va ' + lastPart;
} else {
return parts[0];
}
}
const tripDuration = Temporal.Duration.from({ days: 3, hours: 10, minutes: 45 });
console.log(formatDurationToHumanReadable(tripDuration, 'uz-UZ')); // 3 kun, 10 soat va 45 daqiqa
console.log(formatDurationToHumanReadable(tripDuration, 'en-US')); // 3 days, 10 hours and 45 minutes (misol uchun)
const meetingReminder = Temporal.Duration.from({ minutes: 5 });
console.log(formatDurationToHumanReadable(meetingReminder, 'en-GB')); // 5 daqiqa
const microDuration = Temporal.Duration.from({ nanoseconds: 1234567 });
console.log(formatDurationToHumanReadable(microDuration, 'en-US')); // 1.23 millisekund
Murakkabroq ko'plik shakllari va lokalizatsiyalangan ro'yxat formatlash uchun buni Intl.RelativeTimeFormat yoki murakkabroq satr shablonlari kutubxonalari bilan birlashtirish mumkin. Asosiy narsa - davomiylikni hisoblashni (Temporal tomonidan boshqariladi) uning taqdimotidan (sizning formatlash mantig'ingiz va Intl tomonidan boshqariladi) ajratishdir.
Intl.DurationFormatdan Foydalanish (Kelajak/Taklif)
Hozirda Intl.DurationFormat uchun TC39 taklifi mavjud bo'lib, u davomiyliklarni formatlashning tabiiy, mahalliy tilga mos usulini taqdim etishni maqsad qilgan. Agar standartlashtirilsa va joriy etilsa, u yuqorida ko'rsatilgan qo'lda formatlashni ancha soddalashtirib, JavaScript ekotizimi ichida to'g'ridan-to'g'ri xalqarolashtirish uchun mustahkam yechim taklif qiladi.
U boshqa Intl obyektlariga o'xshab ishlashi mumkin:
// Bu gipotetik va taklifning hozirgi holatiga asoslangan
// Ishlab chiqarishda ishlatishdan oldin brauzer muvofiqligini tekshiring
/*
const duration = Temporal.Duration.from({ days: 1, hours: 2, minutes: 30 });
const formatter = new Intl.DurationFormat('en-US', {
style: 'long',
years: 'long',
days: 'long',
hours: 'long',
minutes: 'long',
});
console.log(formatter.format(duration)); // "1 day, 2 hours, 30 minutes"
const shortFormatter = new Intl.DurationFormat('fr-FR', { style: 'short', hours: 'numeric', minutes: 'numeric' });
console.log(shortFormatter.format(duration)); // "1 j, 2 h, 30 min"
*/
Hali barcha muhitlarda mavjud bo'lmasa-da, ushbu taklifni kuzatib boring, chunki u kelajakda global davomiylikni formatlash uchun yakuniy yechim bo'lishi kutilmoqda.
Amaliy Foydalanish Holatlari va Global Mulohazalar
Temporal.Duration shunchaki akademik yaxshilanish emas; u turli vaqt mintaqalari va madaniyatlarda ishlaydigan ilovalardagi haqiqiy muammolarni hal qiladi.
1. Rejalashtirish va Tadbirlarni Boshqarish
Xalqaro tadbirlar, konferensiyalar yoki uchrashuvlarni boshqaradigan platformalar uchun tadbir davomiyligini, tadbirgacha qolgan vaqtni yoki tanaffus qancha davom etishini hisoblash juda muhim. Temporal.Duration bu hisob-kitoblarning foydalanuvchining joylashuvi yoki mahalliy vaqt mintaqasi qoidalaridan qat'i nazar, aniq bo'lishini ta'minlaydi.
// Global vebinar uchun qolgan vaqtni hisoblash
const now = Temporal.ZonedDateTime.from('2024-07-25T10:00:00[Europe/London]'); // Misol uchun joriy vaqt
const webinarStart = Temporal.ZonedDateTime.from('2024-07-26T14:30:00[Asia/Tokyo]');
const timeUntilWebinar = now.until(webinarStart, {
largestUnit: 'hour',
smallestUnit: 'minute',
roundingMode: 'ceil' // Foydalanuvchilar o'tkazib yubormasligi uchun yuqoriga yaxlitlash
});
console.log(`Vebinar ${timeUntilWebinar.hours} soat va ${timeUntilWebinar.minutes} daqiqadan so'ng boshlanadi.`);
// Natija ushbu ikki ZonedDateTime o'rtasidagi haqiqiy o'tgan vaqtga asoslanib aniq bo'ladi.
2. Ishlash Ko'rsatkichlari va Log Yozish
Operatsiyalarning bajarilish vaqtini, API javob vaqtlarini yoki ommaviy ishlarning davomiyligini o'lchash yuqori aniqlikni talab qiladi. Temporal.Duration, ayniqsa Temporal.Instant (nanosekund aniqlikni taklif qiladi) bilan birgalikda, bu uchun idealdir.
const startTime = Temporal.Instant.now();
// Murakkab operatsiyani simulyatsiya qilish
for (let i = 0; i < 1_000_000; i++) { Math.sqrt(i); }
const endTime = Temporal.Instant.now();
const executionDuration = startTime.until(endTime);
// Ko'rsatish uchun soniya va millisekundlargacha formatlash
const formattedExecution = executionDuration.round({ smallestUnit: 'millisecond', largestUnit: 'second' });
console.log(`Operatsiya ${formattedExecution.seconds}.${String(formattedExecution.milliseconds).padStart(3, '0')} soniya davom etdi.`);
3. Moliyaviy Hisob-kitoblar
Moliyada foizlarni, kredit muddatlarini yoki investitsiya davrlarini hisoblash uchun aniq vaqt oraliqlari juda muhim. Bir davrdagi kunlar, oylar yoki yillarning aniq soni, ayniqsa kabisa yillari yoki ma'lum oylarning uzunligi bilan ishlashda, aniq bo'lishi kerak.
const loanStartDate = Temporal.PlainDate.from('2023-04-01');
const loanEndDate = Temporal.PlainDate.from('2028-03-31');
const loanTerm = loanStartDate.until(loanEndDate, { largestUnit: 'year', smallestUnit: 'month' });
console.log(`Kredit muddati: ${loanTerm.years} yil va ${loanTerm.months} oy.`); // 4 yil va 11 oy
4. Xalqarolashtirish Muammolarini Qayta Ko'rib Chiqish
-
Vaqt Mintaqalari va Yozgi Vaqt:
Temporal.Durationo'zi vaqt mintaqasiga bog'liq emas; u qat'iy vaqt uzunligini ifodalaydi. Biroq, sizDurationniZonedDateTimega qo'shganingizda yoki undan ayirganingizda, Temporal vaqt mintaqasi qoidalarini, shu jumladan Yozgi Vaqtga o'tishlarni to'g'ri qo'llaydi. Bu "24 soatlik davomiylik"ZonedDateTimeni haqiqatan ham 24 soatga oldinga surishini ta'minlaydi, hattoki bu yozgi vaqtga o'tish chegarasini kesib o'tib, *soat* kunini qisqaroq yoki uzunroq qilsa ham. Bu barqarorlik `Date`ga nisbatan katta yutuqdir. -
Madaniy Farqlar: Turli madaniyatlar davomiyliklarni turlicha ifodalaydi.
Temporal.Durationxom komponentlarni (yillar, oylar, kunlar va hokazo) taqdim etsa-da, ularni foydalanuvchining tiliga mos keladigan tarzda taqdim etish uchun `Intl` API-laridan yoki maxsus mantiqdan foydalanish sizning mas'uliyatingizdir. Masalan, ba'zi madaniyatlar "1 soat 30 daqiqa" ni "90 daqiqa" deb ifodalashi yoki turli ko'plik qoidalaridan foydalanishi mumkin. -
Kalendar Tizimlari: Temporal shuningdek, turli kalendar tizimlarini (masalan, yapon, fors, islomiy kalendarlar) qo'llab-quvvatlaydi.
Durationo'zi kalendarga bog'liq bo'lmasa-da, uPlainDateyokiZonedDateTimekabi kalendarga bog'liq turlar bilan o'zaro ta'sir qilganda, arifmetika o'sha kalendarning o'ziga xos qoidalariga rioya qiladi (masalan, bir oydagi kunlar soni, o'sha kalendar ichidagi kabisa yili qoidalari). Bu Gregorian bo'lmagan kalendarlarda sanalarni ko'rsatishi kerak bo'lishi mumkin bo'lgan global ilovalar uchun juda muhimdir.
Temporalning Hozirgi Holati va Qabul Qilinishi
2023 yil oxiri / 2024 yil boshiga kelib, JavaScript Temporal API 3-bosqichdagi TC39 taklifi hisoblanadi. Bu spetsifikatsiya asosan barqaror ekanligini va turli JavaScript dvigatellari va brauzerlarida amalga oshirilayotgani va sinovdan o'tkazilayotganini anglatadi. Chrome, Firefox va Safari kabi yirik brauzerlar Temporalni joriy etish ustida faol ishlamoqda, eksperimental bayroqlar yoki dastlabki versiyalar allaqachon mavjud.
Hali polifillsiz universal darajada mavjud bo'lmasa-da, uning ilg'or bosqichi uning JavaScriptning standart qismiga aylanishi ehtimoli yuqori ekanligini ko'rsatadi. Dasturchilar bugunoq polifillardan foydalanib yoki brauzer ishlab chiqish muhitlarida eksperimental xususiyatlarni yoqib, Temporal bilan tajriba o'tkazishni boshlashlari mumkin. Erta qabul qilish sizga oldinda bo'lish, uning afzalliklarini tushunish va brauzer qo'llab-quvvatlashi kengayib borishi bilan uni loyihalaringizga integratsiya qilish imkonini beradi.
Uning keng tarqalishi natijada tashqi sana/vaqt kutubxonalariga bo'lgan ehtiyojni sezilarli darajada kamaytiradi va JavaScript vaqtini boshqarish uchun mustahkam, tabiiy yechimni taqdim etadi.
Temporal Durationdan Foydalanish Bo'yicha Eng Yaxshi Amaliyotlar
Ilovalaringizda Temporal.Duration afzalliklarini maksimal darajada oshirish uchun ushbu eng yaxshi amaliyotlarni ko'rib chiqing:
-
Temporal.Duration.from()ga Ustunlik Bering: Ma'lum komponentlar yoki ISO satrlaridan davomiylik yaratishda, obyekt literalliTemporal.Duration.from()ko'pincha konstruktorning pozitsion argumentlariga qaraganda o'qilishi osonroq va xatolardan xoli bo'ladi. -
Noaniq Taqqoslashlar Uchun
relativeTodan Foydalaning: Yillar, oylar yoki haftalarni o'z ichiga olgan davomiyliklarni taqqoslash yoki yaxlitlashda har doimrelativeToopsiyasini taqdim eting. Bu kerakli kalendar kontekstini ta'minlab, aniq hisob-kitoblarni kafolatlaydi. -
until()vasince()dan Foydalaning: Ikki aniq vaqt nuqtasi orasidagi intervalni hisoblash uchun Temporal sana-vaqt obyektlaridagiuntil()vasince()metodlarini afzal ko'ring. Ular vaqt mintaqalari va yozgi vaqt murakkabliklarini to'g'ri boshqaradi. -
Ko'rsatish Uchun Normallashtiring va Yaxlitlang: Davomiyliklarni foydalanuvchilarga taqdim etishdan oldin, davomiylikni eng mos va tushunarli birliklarga aylantirish uchun
normalize()va ayniqsaround()dan foydalanishni ko'rib chiqing (masalan, 90 daqiqani "1 soat 30 daqiqa"ga aylantirish). -
Ichki Ko'rinishni Ko'rsatishdan Ajrating: Ichki davomiylik hisob-kitoblaringizni
Temporal.Durationbilan aniq saqlang. Faqat foydalanuvchi interfeysini ko'rsatishda o'zgartiring va formatlang, global aniqlik uchun maxsus formatlash funksiyalari vaIntlAPI-sidan foydalaning. - Yangiliklardan Xabardor Bo'ling: Temporal API-ning rivojlanishi va brauzer muvofiqligini kuzatib boring. U to'liq standartlashishga qarab harakatlanar ekan, ekotizim rivojlanadi va yangi vositalar yoki eng yaxshi amaliyotlar paydo bo'lishi mumkin.
- Aniqlikka E'tiborli Bo'ling: Temporal nanosekund aniqlikni qo'llab-quvvatlasa-da, faqat sizga haqiqatan ham kerak bo'lgan aniqlikdan foydalaning. Yuqori aniqlik ba'zan disk raskadrovka qilishni qiyinlashtirishi yoki pastroq aniqlikdagi displeylarga aylantirilganda kutilmagan yaxlitlashlarga olib kelishi mumkin.
Xulosa
Temporal.Durationning joriy etilishi vaqt oralig'i arifmetikasi bilan kurashayotgan JavaScript dasturchilari uchun muhim yutuqdir. O'zgarmas, aniq va global miqyosda ishlaydigan API taqdim etish orqali Temporal eskirgan Date obyektining uzoq yillik cheklovlarini hal qiladi.
Endi siz murakkab vaqt hisob-kitoblarini ishonch bilan bajarishingiz, davrlarni aniq o'lchashingiz va davomiyliklarni butun dunyodagi foydalanuvchilar uchun ham aniq, ham madaniy jihatdan mos tarzda taqdim etishingiz mumkin. Dasturiy ta'minotning chiqarilish sikli davomiyligini, global mahsulotning ishga tushirilishigacha qolgan vaqtni yoki insonning aniq yoshini hisoblayapsizmi, Temporal.Duration sizga mustahkam va ishonchli ilovalar yaratish uchun kerakli vositalarni taklif qiladi.
Temporal.Durationni qabul qiling va JavaScript loyihalaringizda vaqtni boshqarish usulingizni o'zgartiring. JavaScript-da sana va vaqt bilan ishlashning kelajagi shu yerda, u yanada bashorat qilinadigan, kuchli va global miqyosda mos keladigan ishlab chiqish tajribasini va'da qiladi.